#ifndef __DRV_SPI_NORFLASH_H__
#define __DRV_SPI_NORFLASH_H__

#include "app_config.h"
#include "Type_def.h"

#if TCFG_DRV_SPI_NORFLASH_SUPPORT

#define NORFLASH_PAGE_SIZE          256     // 256Byte
#define NORFLASH_SECTOR_SIZE        4096    // 4KB
#define NROFLASH_HALF_BLOCK_SIZE    32768   // 32KB
#define NORFLASH_BLOCK_SIZE         65536   // 64KB

#define NORFLASH_FATFS_SECTOR_SIZE  (NORFLASH_PAGE_SIZE * 2) // EatFs 文件系统读写扇区大小 支持页擦除的Norflash设置为2页

/* 指令表 */
#define NOR_WriteEnable             0x06    /* 写使能 */    
#define NOR_WriteDisable            0x04    /* 写禁止 */
#define NOR_VolatileSRWriteEnable   0x50    
#define NOR_ReleasePowerDown        0xAB
#define NOR_ManufactDeviceID        0x90
#define NOR_JEDEC_ID                0x9F
#define NOR_ReadUniqueID            0x5A
#define NOR_ReadData                0x03
#define NOR_FastRead                0x0B
#define NOR_PageProgram             0x02
#define NOR_PageErase               0x81    /* 擦除1个页 256字节 ，部分Norflash不支持页擦除！ */
#define NOR_SectorErase_4KB         0x20    /* 擦除1个扇区=4KB */
#define NOR_BlockErase_32KB         0x52    /* 擦除半个块=32KB */
#define NOR_BlockErase_64KB         0xD8    /* 擦除1个块=64KB */
#define NOR_ChipErase               0x60    /* or 0xC7 */

#define NOR_ReadStatusREG1          0x05
#define NOR_WriteStatusREG1         0x01
#define NOR_ReadStatusREG2          0x35
#define NOR_WriteStatusREG2         0x31
#define NOR_ReadStatusREG3          0x15
#define NOR_WriteStatusREG3         0x11

#define NOR_ReadSFDPREG             0x5A
#define NOR_EraseSecurityREG        0x44
#define NOR_ProgramSecurityREG      0x42
#define NOR_ReadSecurityREG         0x48
#define NOR_EraseProgramSuspend     0x75
#define NOR_EraseProgramResume      0x7A
#define NOR_Powerdown               0xB9
#define NOR_EnableReset             0x66
#define NOR_ResetDevice             0x99

#define NOR_FastReadDualOutput      0x3B
#define NOR_FastReadDual_IO         0xBB
#define NOR_QuadInputPageProgram    0x32
#define NOR_FastReadQuadOutput      0x6B
#define NOR_FastReadQuad_IO         0xEB
#define NOR_WordReadQuad_IO         0xE7
#define NOR_SetBurstWithWrap        0x77

#define NOR_DummyByte               0xFF


enum {
    NORFLASH_ERASE_PAGE=0,      /* 擦除页   256Byte */
    NORFLASH_ERASE_SECTOR,      /* 擦除扇区 4KB */
    NORFLASH_ERASE_HALF_BLOCK,  /* 擦除半块 32KB*/
    NORFLASH_ERASE_BLOCK,       /* 擦除整块 64KB*/
    NORFLASH_ERASE_ALLCHIP,     /* 擦除全部空间  */
};



// #pragma pack(1)
// #pragma pack()

// #pragma pack(push,1) 
// #pragma pack(pop) 

#pragma pack(1)
struct norflash_reg_t{
    union {        
        struct {
            uint8_t BUSY:1;     // S0
            uint8_t WEL: 1;     // S1
            uint8_t PB0: 1;     // S2
            uint8_t PB1: 1;     // S3
            uint8_t BP2: 1;     // S4
            uint8_t _TB: 1;     // S5
            uint8_t _SEC: 1;    // S6
            uint8_t SRP0: 1;    // S7
        }R;
        uint8_t _data;           
    }REG1;

    union {        
        struct {
            uint8_t SRP1: 1; // S8
            uint8_t _QE: 1; // S9
            uint8_t LB0: 1; // S10
            uint8_t LB1: 1; // S11
            uint8_t LB2: 1; // S12
            uint8_t LB3: 1; // S13
            uint8_t CMP: 1; // S14
            uint8_t SUS: 1; // S15
        }R;
        uint8_t _data;
    }REG2;
    
    union {        
        struct {
            uint8_t Reserved2: 5;
            // uint8_t DRV2: 1; // S21
            uint8_t DRVS: 2; // S21 S22
            uint8_t Reserved1: 1;    // S23
        }R;
        uint8_t _data;
    }REG3;
};
#pragma pack()

struct jedec_id_t {
    uint8_t manufacturer_id;    /* 制造商ID */
    uint8_t memory_type;        /* 存储类型 */
    uint8_t capacity;           /* 存储容量 */
};

struct norflash_dev_t {    
    uint16_t device_id;
    uint32_t page_size;
    uint32_t sector_size;
    uint32_t sector_count;
    uint32_t block_size;

    struct jedec_id_t jedec_id;
    struct norflash_reg_t reg;
};

struct norflash_dev_t* NorFlash_Handler(void);

void NorFlash_Read_JEDEC_ID(void);

uint16_t NorFlash_ReadID(void);

void NorFlash_ReadStatus(void);

void NorFlash_Sleep(void);

void NorFlash_Wakeup(void);

uint8_t NorFlash_Erase(uint8_t eraser, uint32_t address);

uint8_t NorFlash_ReadBuffer(uint8_t *buffer, uint32_t address, uint32_t len);

uint8_t NorFlash_WritePage(uint8_t *buffer, uint32_t address,  uint32_t len);

uint8_t NorFlash_WriteBuffer(uint8_t *buffer, uint32_t address,  uint32_t len);

uint8_t NorFlash_Init(void);

uint8_t NorFlash_GPIO_Config(void);

void NorFlash_Test(void);

#endif

#endif